﻿using System.ClientModel;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Transport;
using OpenAI;

var builder = Host.CreateApplicationBuilder(args);
builder.Configuration.AddJsonFile("appsettings.json");
builder.Logging.AddConsole();
var host = builder.Build();
//【1】加载MCP服务
////sse方式加载
//var clientSse = new SseClientTransport(new()
//{
//    Name = "Demo Sse Server",
//    Endpoint = new Uri("http://localhost:5066/sse"),
//    AdditionalHeaders = []
//});
//std方式加载
var clientTransport = new StdioClientTransport(new()
{
    Name = "Demo Std Server",
    //Command = "uvx",
    //Arguments = ["mcp-server-fetch",]
    Command = "cmd",
    Arguments = ["/C",
        "C:\\Users\\zhouh\\RiderProjects\\SauryMCP\\Saury.McpServer\\bin\\Debug\\net8.0\\server.exe"],
    EnvironmentVariables = [],
    //uvx mcp-server;npx mcp-server;
    //python index.py;node index.py
    //dotnet run --project MyProject.csproj --no-build;../server.exe

}); Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("MCP Client Started!");
Console.ResetColor();
await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport);
//列出所有加载的服务中的所有方法
var mcpTools = await mcpClient.ListToolsAsync();
foreach (var tool in mcpTools)
{
    Console.WriteLine($"工具：{tool.Name}\n描述：{tool.Description}");
}
//【2】模拟直接调用MCP工具(一般不会这样用)
// var result = await mcpClient.CallToolAsync(
//     "GetCurrentTime",
//     new Dictionary<string, object?>() { ["city"] = "Chengdu" }
//     );
// Console.WriteLine(result.Content.First(c => c.Type == "text").Text);
//【3】LLM大模型自动调用MCP工具
// Microsoft.Extensions.AI;Microsoft.Extensions.AI.OpenAI
// 获取配置，通过层级路径获取配置值
var config = host.Services.GetRequiredService<IConfiguration>();
//通过配置文件获取大模型配置，本次使用了硅基流动的API
string apiKey = config["LLM:ApiKey"];
var apiKeyCredential = new ApiKeyCredential(apiKey );
var aiClientOptions = new OpenAIClientOptions();
aiClientOptions.Endpoint = new Uri(config["LLM:EndPoint"]);
var aiClient = new OpenAIClient(apiKeyCredential, aiClientOptions)
    .AsChatClient(config["LLM:ModelId"]);
var chatClient = new ChatClientBuilder(aiClient)
    .UseFunctionInvocation()
    .Build();
//系统提示词System,Assistant,User
IList<ChatMessage> chatHistory =
[
    new(ChatRole.System, """你是一个智能助手，能加载MCP服务，为用户提供城市时间查询等"""),
];
var chatOptions = new ChatOptions()
{
    Tools = [.. mcpTools]
};
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Assistant> 我该样帮助你?");
while (true)
{
    Console.ForegroundColor = ConsoleColor.White;
    Console.Write("User> ");
    var question = Console.ReadLine();
    // 用户输入EXIT或者空格后按下Enter会退出循环，进而退出程序
    if (!string.IsNullOrWhiteSpace(question) && question.ToUpper() == "EXIT")
        break;
    chatHistory.Add(new ChatMessage(ChatRole.User, question));
    Console.ForegroundColor = ConsoleColor.Green;
    // 向AI提问的时候，附加上MCP的工具，启用FunCall功能后AI会自主调用
    var response = await chatClient.GetResponseAsync(chatHistory, chatOptions);
    var content = response.ToString();
    Console.WriteLine($"Assistant> {content}");
    chatHistory.Add(new ChatMessage(ChatRole.Assistant, content));
    Console.WriteLine();
}
await host.RunAsync(); // 阻塞在这里，后续代码不会执行